const toString = Object.prototype.toString;

function dump_object(obj) {
  var buff, prop;
  buff = [];
  for (prop in obj) {
    buff.push(serialize(prop, ':') + serialize(obj[prop]))
  }
  return '{\n' + buff.join(',\n') + '}';
}

function dump_array(arr) {
  var buff, i, len;
  buff = [];
  for (i = 0, len = arr.length; i < len; i++) {
    buff.push(serialize(arr[i]));
  }
  return '[' + buff.join(', ') + ']';
}

function serialize(obj, str) {
  if (toString.call(obj) == '[object Function]') {
    return obj.toString();
  } else if (toString.call(obj) == '[object Array]') {
    return dump_array(obj);
  } else if (toString.call(obj) == '[object String]') {
    return str ? obj + str : '"' + obj.replace('"', '\\"') + '"';
  } else if (toString.call(obj) == '[object Number]' || toString.call(obj) == '[object Boolean]') {
    return obj
  }
  else if (obj === Object(obj)) {
    return dump_object(obj);
  }
  return obj.toString();
}

module.exports = serialize